summaryrefslogtreecommitdiffstats
path: root/domain2name.c
blob: 46fd2a373ff75231e64a0dfa74eb9e8deca5cec1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int domain2name_len (const char * s, int l) {
	int r = 1; /* ending terminator */
	int o = 0; /* label offset */
	for (int i = 0; i < l; i++) {
		if (s[i] == '.') {
			if (!o) /* double period or starting period, label is empty */
				break;
			o = 0;
			continue;
		}
		if (!o) /* label has started */
			r++;
		r++;
		o++;
	}
	return r;
}
int domain2name (char * d, const char * s, int l) { /* l is length of s */
	char * c = d; /* where to write the label size when done with label */
	char * w = d;
	int o = 0; /* label offset */
	for (int i = 0; i <= l /* yes, we go one more ... */; i++) {
		if (i == l /* ... here */ || s[i] == '.') { /* end of label or end of last label */
			if (!o) /* double period or starting period, label is empty */
				break;
			if (o <= 63) /* max length of label (six bits) */
				*c = o;
			o = 0;
			continue;
		}
		if (!o++) /* label has started */
			c = w++; /* to be filled with length */
		if (o <= 63)
			*w++ = s[i];
		if (o == 64) /* if this label is too long, instead of writing it, we silently cap */
			*c = 63; /* it at 63 bytes */
	}
	*w++ = '\0'; /* luckily this makes domain2name kind of safe for handling as a string (: */
	return w-d; /* we return number of bytes written */
} /* d must be allocated for at least _len. */